#include "StdAfx.h"
#include "CookraceMachine.h"

CCookraceMachine::CCookraceMachine()
{
}

CCookraceMachine::~CCookraceMachine()
{
}

int CCookraceMachine::Init()
{
CBurgerTimeMachine::Init();
MainCPU->SetUser(this);
SoundCPU->SetUser(this);
MainCPU->SetRead(ReadMainCPU);
MainCPU->SetWrite(WriteMainCPU);
MainCPU->SetOp(OpMainCPU);								//reading decrypted opcodes
SoundCPU->SetRead(ReadSoundCPU);
SoundCPU->SetWrite(WriteSoundCPU);
SoundCPU->SetOp(ReadSoundCPU);
return(0);
}

void CCookraceMachine::Reset()
{
int n;

CBurgerTimeMachine::Reset();
for(n=0;n<0x10000;n++)
	NewROM[n] = Decrypt(MainROM[n]);
for(n=0;n<0x10;n++)
	WritePalette(n,~PROM[n]);
memcpy(BGROM + 0x0000,Temp + 0x800,0x800);
memcpy(BGROM + 0x0800,Temp + 0x1800,0x800);
memcpy(BGROM + 0x1000,Temp + 0x2800,0x800);
}

void CCookraceMachine::SaveState(CState *s)
{
CBurgerTimeMachine::SaveState(s);
s->Write(VRAM,0x800);
}

void CCookraceMachine::LoadState(CState *s)
{
CBurgerTimeMachine::LoadState(s);
s->Read(VRAM,0x800);
}

void CCookraceMachine::RenderScreen(u8 *dest,int pitch)
{
memset(dest,0,256*pitch);
RenderBackground(dest,pitch);
RenderChars(dest,pitch);
RenderSprites(dest,pitch);
}

void CCookraceMachine::RenderBackground(u8 *dest,int pitch)
{
int i,x,y;
u8 *b[3];

b[0] = BGROM + 0x0000;
b[1] = BGROM + 0x0800;
b[2] = BGROM + 0x1000;
for(i=0x3FF;i>=0;i--)
	{
	x = 31 - (i / 32);
	y = i & 0x1F;
	if(VideoControl & 1)
		{
		x = 31 - x;
		y = 31 - y;
		}
	drawtile_8x8(dest,pitch,VRAM[i+0x400],(u8)x*8,(u8)y*8,b);
	}
}

u8 CCookraceMachine::OpMainCPU(void *user,u32 addr)
{
CCookraceMachine *M = (CCookraceMachine*)user;

return(M->NewROM[addr]);
}

u8 CCookraceMachine::ReadMainCPU(void *user,u32 addr)
{
CCookraceMachine *M = (CCookraceMachine*)user;

if(addr < 0x4000)
	{
	if(addr >= 0x500)
		return(M->MainROM[addr]);
	if(addr < 0x400)
		return(M->MainRAM[addr]);
	}
switch(addr & 0xFC00)
	{
	case 0xC000:
		return(M->VideoRAM[addr & 0x3FF]);
	case 0xC400:
		return(M->ColorRAM[addr & 0x3FF]);
	case 0xC800:
		addr &= 0x3FF;
		return(M->VideoRAM[MirrorRAMAddr(addr)]);
	case 0xCC00:
		addr &= 0x3FF;
		return(M->ColorRAM[MirrorRAMAddr(addr)]);
	case 0xD000:
	case 0xD400:
		return(M->VRAM[addr & 0x7FF]);
	case 0xE000:
		switch(addr)
			{
			case 0xE300:
			case 0xE000:	return((M->Dip[0] & 0x7F) | M->VBlank);
			case 0xE001:	return(M->Dip[1]);
			case 0xE002:	return(M->InputData[0]);
			case 0xE003:	return(M->InputData[1]);
			case 0xE004:	return(M->InputData[2]);
			}
		break;
	case 0xFC00:
		if(addr >= 0xFFE0)
			return(M->MainROM[addr]);
		break;
	}
message("unhandled read (main cpu, addr $%04X)\n",addr);
return(0);
}

void CCookraceMachine::WriteMainCPU(void *user,u32 addr,u8 data)
{
CCookraceMachine *M = (CCookraceMachine*)user;

switch(addr & 0xFC00)
	{
	case 0x0000:
		M->MainRAM[addr] = data;
		return;
	case 0xC000:
		M->VideoRAM[addr & 0x3FF] = data;
		return;
	case 0xC400:
		M->ColorRAM[addr & 0x3FF] = data;
		return;
	case 0xC800:
		addr &= 0x3FF;
		M->VideoRAM[MirrorRAMAddr(addr)] = data;
		return;
	case 0xCC00:
		addr &= 0x3FF;
		M->ColorRAM[MirrorRAMAddr(addr)] = data;
		return;
	case 0xD000:
	case 0xD400:
		M->VRAM[addr & 0x7FF] = data;
		return;
	case 0xE000:
		if(addr == 0xE000)
			{
			M->VideoControl = data;
			return;
			}
		if(addr == 0xE001)
			{
			M->WriteSoundControl(data);
			return;
			}
		break;
	}
message("unhandled write (main cpu, addr $%04X = $%02X)\n",addr,data);
}

u8 CCookraceMachine::ReadSoundCPU(void *user,u32 addr)
{
CCookraceMachine *M = (CCookraceMachine*)user;

if(addr < 0x1000)
	{
	if(addr < 0x200)
		return(M->SoundRAM[addr]);
	return(M->SoundROM[addr]);
	}
if(addr >= 0xF000)
	return(M->SoundROM[addr & 0xFFF]);
return(CBurgerTimeMachine::ReadSoundCPU(user,addr));
}

void CCookraceMachine::WriteSoundCPU(void *user,u32 addr,u8 data)
{
CCookraceMachine *M = (CCookraceMachine*)user;

if(addr < 0x200)
	{
	M->SoundRAM[addr] = data;
	return;
	}
CBurgerTimeMachine::WriteSoundCPU(user,addr,data);
}

